package com.git.hui.yinshua.biz.pay.dao.repository;

import com.git.hui.yinshua.api.model.ReqInfoContext;
import com.git.hui.yinshua.api.model.order.PayStatusEnum;
import com.git.hui.yinshua.api.model.order.PayTypeEnum;
import com.git.hui.yinshua.api.model.order.RefundStatusEnum;
import com.git.hui.yinshua.api.model.order.TradeStatusEnum;
import com.git.hui.yinshua.biz.pay.dao.entity.OrderPaymentEntity;
import com.git.hui.yinshua.biz.pay.dao.entity.OrderRefundEntity;
import com.git.hui.yinshua.biz.pay.dao.mapper.OrderPaymentMapper;
import com.git.hui.yinshua.biz.rest.models.order.rsp.OrderDto;
import com.git.hui.yinshua.biz.user.service.UserService;
import com.git.hui.yinshua.biz.util.PriceUtil;
import com.git.hui.yinshua.common.DateUtil;
import com.git.hui.yinshua.common.id.OrderIdGen;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @author YiHui
 * @date 2024/9/9
 */
@Repository
public class OrderPaymentRepository {
    @Autowired
    private OrderPaymentMapper orderPaymentMapper;
    @Autowired
    private UserService userService;


    public OrderPaymentEntity queryForLockByOutId(String outTradeId) {
        return orderPaymentMapper.queryByUuidForUpdate(outTradeId);
    }

    /**
     * 根据订单查询支付单
     *
     * @param orderId
     * @return
     */
    public OrderPaymentEntity queryByOrderId(Long orderId) {
        return orderPaymentMapper.queryByOrderId(orderId);
    }

    /**
     * 批量查询支付单信息
     *
     * @param orderIds
     * @return
     */
    public List<OrderPaymentEntity> batchQueryByOrderIs(Collection<Long> orderIds) {
        if (CollectionUtils.isEmpty(orderIds)) {
            return Collections.emptyList();
        }
        return orderPaymentMapper.batchQueryByOrderId(orderIds);
    }


    /**
     * 获取or生成订单对应的支付单
     *
     * @param order 订单
     * @return 支付单
     */
    public OrderPaymentEntity getOrSavePayment(OrderDto order) {
        OrderPaymentEntity payment = orderPaymentMapper.queryByOrderId(order.getOrderId());
        if (payment == null) {
            // 支付单不存在，创建一个新的
            payment = new OrderPaymentEntity();
            payment.setId(OrderIdGen.genPayId());
            payment.setOrderId(order.getOrderId());
            payment.setUid(order.getUser().getUserId());
            payment.setOrderAmount(PriceUtil.toCentPrice(order.getPayAmount()));
            payment.setPayAmount(payment.getOrderAmount());
            payment.setPayStatus(PayStatusEnum.TO_PAY.getStatus());
            payment.setPayType(PayTypeEnum.WEIXIN.getType());
            payment.setActualAmount(payment.getPayAmount());
            payment.setCurrency("CNY");
            // 直接以订单作为唯一支付建，避免重复支付
            // fixme 这种设计方式，不支持多订单一次支付的场景
            payment.setUuid("ZF" + order.getOrderId());
            payment.setThirdTransCode("");
            payment.setTradeStatus(TradeStatusEnum.NOT_PAY.getStatus());
            payment.setPrePayId("");
            payment.setPreExpireTime(System.currentTimeMillis());
            payment.setOpenId(userService.getUserInfo(ReqInfoContext.getReqInfo().getUserId()).getWxId());
            payment.setRemark("");
            orderPaymentMapper.savePayment(payment);
            return payment;
        }

        return payment;
    }


    public void updatePrePayInfo(OrderPaymentEntity payment) {
        orderPaymentMapper.updatePrePayId(payment.getId(), payment.getPrePayId(), DateUtil.parse2seconds(payment.getPreExpireTime()));
    }

    /**
     * 更新支付单为支付中
     *
     * @param orderId
     * @return
     */
    public boolean updatePaying(long orderId) {
        return orderPaymentMapper.updatePaying(orderId) > 0;
    }


    /**
     * 微信支付回调，更新微信相关的流水信息
     *
     * @param payment
     * @return
     */
    public boolean updatePayInfo(OrderPaymentEntity payment) {
        return orderPaymentMapper.updatePayment(payment) > 0;
    }


    // ------------------ 退款相关

    /**
     * 添加退款
     *
     * @param payment
     * @param notes
     * @return
     */
    public OrderRefundEntity saveRefund(OrderPaymentEntity payment, String notes) {
        OrderRefundEntity refund = new OrderRefundEntity();
        refund.setId(OrderIdGen.genRefundId());
        refund.setOrderId(payment.getOrderId());
        refund.setPaymentId(payment.getId());
        refund.setRefundAmount(payment.getActualAmount());
        refund.setCurrency(payment.getCurrency());
        // fixme 将支付单号作为外部退款单号，因此我们这里不支持多次退款
        refund.setUuid("TK" + payment.getId());
        refund.setThirdTransCode(null);
        refund.setWxRefundId(null);
        refund.setRemark("");
        refund.setNotes(notes);
        refund.setRefundStatus(RefundStatusEnum.TO_REFUND.getStatus());
        orderPaymentMapper.saveRefund(refund);
        return refund;
    }

    public OrderRefundEntity queryRefundByUuidForUpdate(String uuid) {
        return orderPaymentMapper.queryRefundByUuidForUpdate(uuid);
    }

    public List<OrderRefundEntity> batchQueryRefundByOrderId(Collection<Long> orderIds) {
        if (CollectionUtils.isEmpty(orderIds)) {
            return Collections.emptyList();
        }
        return orderPaymentMapper.batchQueryRefundByOrderId(orderIds);
    }

    public boolean updateRefundInfo(OrderRefundEntity refund) {
        // 退款回调，更新相关信息
        if (refund.getRefundTime() != null) {
            // 退款时间更新的兼容
            refund.setRefundTime(DateUtil.parse2seconds(refund.getRefundTime()));
        }
        return orderPaymentMapper.updateRefundInfo(refund) > 0;
    }
}
